
import threading
import logging
from pathlib import Path
import cv2
import os
import time
import copy

from watchdog import WatchDog

def ffmpeg_read(url, cache_file):
    cmd_str = "ffmpeg -loglevel 0 -rtsp_transport tcp -i "+ url +" -y -f mjpeg -vframes 1 " + cache_file
    # cmd_str = ('ffmpeg -loglevel 0 -c:v h264_bm -rtsp_transport tcp -i ' + url 
    #     + '-vf "scale_bm=format=yuvj420p:zero_copy=1" -c:v jpeg_bm -vframes 1 -y '  + cache_file)
    logging.info("ffmpeg decode: %s" % cmd_str)
    retval = os.system(cmd_str)
    return retval == 0

class CameraManager:
    def __init__(self, urls):
        self.urls = urls
        self.frames = {}
        self.init = False
        self.lock = threading.Lock()
        self._cache_dir = Path('ffmpeg_cache')
        self._cache_dir.mkdir(parents=True, exist_ok=True)
        self.watchdog = WatchDog(limit_time=90, name="camera_dog")

        thread = threading.Thread(target=self._thread_fn, name="camare_manager_thread")
        thread.daemon = True
        thread.start()

    def _thread_fn(self):
        while True:
            for uid, link in self.urls.items():
                while True:
                    cache_file = self._cache_dir / ("%s.jpg" % uid)
                    success = ffmpeg_read(link, str(cache_file))
                    if success:
                        with self.lock:
                            self.frames[uid] = cv2.imread(str(cache_file))
                        break
                    else:
                        logging.warn("ffmpeg_read fail once: %s, %s" % (uid, link))
                        time.sleep(0.5)
                time.sleep(0.5)
            self.init = True
            self.watchdog.feed()

    def read_all_cameras(self):
        while True:
            with self.lock:
                if self.init:
                    return copy.deepcopy(self.frames)
            time.sleep(0.1)